package com.vhall.component.service.room.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vhall.component.dao.room.InvestRefRelationMapper;
import com.vhall.component.entity.room.entity.InvestRefRelationEntity;
import com.vhall.component.entity.room.vo.AddInvestRefRelationVO;
import com.vhall.component.entity.room.vo.DeleteInvestRefRelationRequestVO;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.Token;
import com.vhall.component.plugin.common.support.TokenThreadLocal;
import com.vhall.component.service.room.InvestRefRelationService;
import com.vhall.component.service.room.RoomInnerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author xing.wang
 * @description 针对表【invest_ref_relation(投资依据关联表)】的数据库操作Service实现
 * @createDate 2023-08-08 09:53:58
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InvestRefRelationServiceImpl extends ServiceImpl<InvestRefRelationMapper, InvestRefRelationEntity>
        implements InvestRefRelationService {
    private final InvestRefRelationMapper investRefRelationMapper;

    private final RoomInnerService roomInnerService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addInvestRefRelation(AddInvestRefRelationVO vo) {
        Token token = TokenThreadLocal.getToken();
        Integer accountId = token.getAccountId();
        int ilId = Optional.ofNullable(vo.getIlId()).orElse(0);
        int roomDraftRecordId = Optional.ofNullable(vo.getRoomDraftRecordId()).orElse(0);
        if (ilId >= 1) {
            Optional.ofNullable(roomInnerService.getRoomInfoById(ilId)).orElseThrow(() -> new BusinessException(BizErrorCode.EMPTY_ROOM));
        }
        List<Integer> investRefIds = vo.getInvestRefIds();
        LambdaQueryWrapper<InvestRefRelationEntity> irrWhere = Wrappers.lambdaQuery();
        irrWhere.in(InvestRefRelationEntity::getInvestRefId, investRefIds);
        if (ilId >= 1) {
            irrWhere.eq(InvestRefRelationEntity::getIlId, ilId);
        }
        if (roomDraftRecordId >= 1) {
            irrWhere.eq(InvestRefRelationEntity::getRoomDraftRecordId, roomDraftRecordId);
        }
        List<InvestRefRelationEntity> investRefRelationEntities = investRefRelationMapper.selectList(irrWhere);
        if (CollUtil.isNotEmpty(investRefRelationEntities)) {
//        已经存在的关联
            List<Integer> existsRelation = investRefRelationEntities.stream().filter(data -> investRefIds.contains(data.getInvestRefId())).map(InvestRefRelationEntity::getInvestRefId).collect(Collectors.toList());
//        要删除的关联
            List<Integer> deleteRelation = investRefRelationEntities.stream().filter(data -> !investRefIds.contains(data.getInvestRefId())).map(InvestRefRelationEntity::getInvestRefId).collect(Collectors.toList());
//            要新建的关联
            List<Integer> addRelation = investRefIds.stream().filter(data -> !existsRelation.contains(data)).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(deleteRelation)) {
                irrWhere.in(InvestRefRelationEntity::getInvestRefId, deleteRelation);
                investRefRelationMapper.delete(irrWhere);
            }
            if (CollUtil.isNotEmpty(addRelation)) {
                batchInsertRelation(accountId, ilId, roomDraftRecordId, addRelation);
            }
        } else {
            if (CollUtil.isNotEmpty(investRefIds)) {
                batchInsertRelation(accountId, ilId, roomDraftRecordId, investRefIds);
            }
        }

        return true;
    }

    private void batchInsertRelation(Integer accountId, Integer ilId, Integer roomDraftRecordId, List<Integer> addRelation) {
        LocalDateTime now = LocalDateTime.now();
        List<InvestRefRelationEntity> addData = new ArrayList<>();
        for (Integer investRefId : addRelation) {
            addData.add(buildNewInvestRefRelationEntity(accountId, ilId, roomDraftRecordId, now, investRefId));
        }
        this.saveOrUpdateBatch(addData);
    }

    @NotNull
    private InvestRefRelationEntity buildNewInvestRefRelationEntity(Integer accountId, Integer ilId, Integer roomDraftRecordId, LocalDateTime now, Integer investRefId) {
        InvestRefRelationEntity temp = new InvestRefRelationEntity();
        temp.setInvestRefId(investRefId);
        temp.setIlId(ilId);
        temp.setRoomDraftRecordId(roomDraftRecordId);
        temp.setAccountId(accountId);
        temp.setUpdateBy(accountId);
        temp.setCreatedAt(now);
        temp.setUpdatedAt(now);
        return temp;
    }

    @Override
    public Boolean deleteInvestRefRelation(DeleteInvestRefRelationRequestVO vo) {
        return this.removeById(vo.getInvestRefRelationId());
    }
}




